/***************************************************************************************************
 *Copyright(C),2010-2016,Sumscope
 *FileName	:  JsonWriter.cpp
 *Author	:  scofined.qi
 *Version	:  1.0
 *Date		:  2016/09/12
 *Desc		:  //用于主要说明此程序文件完成的主要功能
 *Relation :
 *Others	:  //其他内容说明
 *Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
 *History	:
 * //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
 ***************************************************************************************************/
#include "include/JsonWriter.h"

namespace qb {
typedef base::JsonWriter::Element Element;
static const Element COMMA = ',';
static const Element SEMICOLON = ':';
static const Element LIST_START = '[';
static const Element LIST_END = ']';
static const Element MAP_START = '{';
static const Element MAP_END = '}';
static const Element QUOTATION = '"';

base::JsonWriter::JsonWriter(int initCapcity /*= 0*/)
    : m_count(0),
      m_finished(false),
      m_rootmap(false),
      m_rootlist(false),
      m_format(false),
      m_level(0) {
  initCapcity =
      (initCapcity > 0 && initCapcity < 16 * 1024 * 1024) ? initCapcity : 0;
  m_buffer = new Buffer(initCapcity);
}

base::JsonWriter::~JsonWriter() {
  if (m_buffer) {
    delete m_buffer;
    m_buffer = NULL;
  }
}
void base::JsonWriter::Reset() {
  // 保留内存反复使用
  m_count = 0;
  m_finished = false;
  m_rootmap = false;
  m_rootlist = false;
  m_format = false;
  m_level = 0;
  m_buffer->Reset();
}
int base::JsonWriter::GetCapcity() const { return m_buffer->getcapcity(); }

void base::JsonWriter::Start(int capcity) {
  m_count = 0;
  m_finished = false;
  m_buffer->clear();
  m_buffer->setcapcity(capcity);
  memset(m_buffer->GetBuffer(), 0, m_buffer->getcapcity() * sizeof(Element));
  AddString(&MAP_START, 1);
}
void base::JsonWriter::SeekPos(int pos) { m_buffer->remove_tail(pos); }
const base::JsonWriter::Element* base::JsonWriter::c_str() {
  if (!m_finished) {
    m_finished = true;
    if (!m_rootmap && !m_rootlist) AddString(&MAP_END, 1);
  }
  return m_buffer->GetBuffer();
}

int base::JsonWriter::size() {
  if (!m_finished) {
    m_finished = true;
    if (!m_rootmap && !m_rootlist) AddString(&MAP_END, 1);
  }
  return m_buffer->size();
}

base::JsonWriter::Writer* base::JsonWriter::AddMap(const Element* name) {
  if (m_count > 0) AddString(&COMMA, 1);
  AddName(name, 0);
  AddString(&SEMICOLON, 1);
  m_count++;
  return this;
}

base::JsonWriter::Writer* base::JsonWriter::AddList(const Element* name) {
  if (m_count > 0) AddString(&COMMA, 1);
  AddName(name, 0);
  AddString(&SEMICOLON, 1);
  m_count++;
  return this;
}
void base::JsonWriter::AddNewLine() {
  if (!m_format) return;
  AddString("\r\n", 2);
  for (int i = 0; i < m_level; i++) AddString("  ", 2);
}
void base::JsonWriter::AddName(const Element* name, int len /*= 0*/) {
  AddString(&QUOTATION, 1);
  AddString(name, len);
  AddString(&QUOTATION, 1);
}

void base::JsonWriter::AddJsonString(const Element* str, int len /*= 0*/) {
  AddString(&QUOTATION, 1);
  len = str ? (len <= 0 ? strlen(str) : len) : 0;
  if (len > 0) {
    for (int i = 0; i < len; i++) {
      const Element& t = str[i];
      if (t == (Element)'\\' || t == (Element)'"') {
        m_buffer->Add((Element)'\\');
        m_buffer->Add(t);
      } else if (t == (Element)'\r') {
        m_buffer->Add((Element)'\\');
        m_buffer->Add((Element)'r');
      } else if (t == (Element)'\n') {
        m_buffer->Add((Element)'\\');
        m_buffer->Add((Element)'n');
      } else
        m_buffer->Add(t);
    }
  }
  AddString(&QUOTATION, 1);
}

void base::JsonWriter::AddString(const Element* str, int len /*= 0*/) {
  if (str) {
    len = len <= 0 ? strlen(str) : len;
    if (len > 0) m_buffer->append(str, len);
  }
}

void base::JsonWriter::JsonWriterList::End() {
  if (m_writer) {
    if (m_count <= 0)
      m_writer->AddString(&LIST_START, 1);
    else
      m_writer->AddNewLine();
    m_writer->AddString(&LIST_END, 1);
    m_writer->SetLevel(m_writer->GetLevel() - 1);
  }
  m_writer = 0;
}

void base::JsonWriter::JsonWriterList::AddHead() {
  m_writer->AddString(m_count <= 0 ? &LIST_START : &COMMA, 1);
  m_count++;
  m_writer->AddNewLine();
}

void base::JsonWriter::JsonWriterMap::End() {
  if (m_writer) {
    if (m_count <= 0)
      m_writer->AddString(&MAP_START, 1);
    else
      m_writer->AddNewLine();
    m_writer->AddString(&MAP_END, 1);
    m_writer->SetLevel(m_writer->GetLevel() - 1);
  }
  m_writer = 0;
}

void base::JsonWriter::JsonWriterMap::AddHead() {
  m_writer->AddString(m_count <= 0 ? &MAP_START : &COMMA, 1);
  m_writer->AddNewLine();
  m_count++;
}

void base::JsonWriter::JsonWriterMap::AddHeadAndName(const Element* name,
                                                     int len) {
  AddHead();
  m_writer->AddName(name, len);
  m_writer->AddString(&SEMICOLON, 1);
}

}  // namespace qb
